#ifndef CONNECTIONTHREAD_H
#define CONNECTIONTHREAD_H

#define AIBO_MENU_COMMAND_PORT      10020
#define AIBO_WALKING_COMMAND_PORT   10050
#define AIBO_HEADPOINT_COMMAND_PORT 10052
#define AIBO_TOGGLING_BEHAVIOR_PORT 10053
#define AIBO_CAMERA_PORT            10011
#define AIBO_JOINT_MONITOR_PORT     20002

#define TEKKOTSUMON_JOINT_MONITOR       "!root \"Mode Switch\" \"Joint\"\n"
#define TEKKOTSUMON_WALK_REMOTE_CONTROL "!root \"TekkotsuMon\" \"Walk Remote Control\"\n"
#define TEKKOTSUMON_HEAD_REMOTE_CONTROL "!root \"TekkotsuMon\" \"Head Remote Control\"\n"

#define CMD_TOGGLE_VISION   "!root \"TekkotsuMon\" \"Raw Cam Server\"\r\n"

#define MAX_TRIES 10

#include <QThread>
#include <QtNetwork/QtNetwork>
#include <QDebug>
#include <CommonDefs.h>
#include <AiboState.h>

class AIBOPacket
{
public:
    uint nameLen;
    QString name;
    uint imageEncoding;
    uint imageCompression;
    uint imageWidth;
    uint imageHeight;
    uint imageTimestamp;
    uint imageFramenumber;

    // Generator info
    uint generatorNameLen;
    QString generatorName;
    uint generatorImageWidth;
    uint generatorImageHeight;
    uint generatorImageLayer;
    uint generatorImageChannel;

    uint specificGenNameLen;
    QString specificGenName;
    uint jpegImageDataSize;
};

class ConnectionThread : public QThread
{
    Q_OBJECT
public:
    explicit ConnectionThread(QString host, AiboState* state, QObject *parent = 0);

    void startBehavior();
    void walkForward();
    void stopForward();
    void stopBehavior();
    void closeConnection();

	void sendCmd( const QByteArray& cmd);
    void sendWalkCmd(char type, float amount);
    void sendHeadPointCmd(char type, float amount);
	bool isAlive();
	void killConnection();
	void requestSendCmd(const QByteArray& cmd);
	void requestSendWalkCmd(char type, float amount);
	void requestSendHeadCmd(char type, float amount);

    bool isTcpConnected();
    bool isWalkConnected();
    bool isHeadConnected();
    bool isBehaviorConnected();
    bool isJointMonitorConnected();
    bool isCameraConnected();

    QByteArray getCurrImageData();
    int getCameraWidth();
    int getCameraHeight();

signals:
    
public slots:
    void readMenu();
    void readWalk();
    void readHead();
    void readBehavior();
    void readJoint();
    void readCamera();
    void displaySocketError(QAbstractSocket::SocketError error);
private:
    void run();

    void initCommunication();
    void initRemoteWalkControl();
    void initRemoteHeadControl();
    void initBehavior();
    void initJointMonitor();
    void initCamera();
    
    void checkWalkCommandReady();
    void checkHeadCommandReady();

    void parsePacket(const QByteArray &packet);

private:
    QString m_host;

    bool m_tcpConnected;
    bool m_walkConnected;
    bool m_headConnected;
    bool m_behaviorConnected;
    bool m_jointMonitorConnected;
    bool m_cameraConnected;

	bool alive;

	bool m_cmd;
	QByteArray m_cmdData;

	bool m_move;
	char m_moveType;
	float m_moveAmount;

    bool m_head;
    char m_headType;
    float m_headAmount;

    QTcpSocket* m_menuCmdClient;
    QTcpSocket* m_walkCmdClient;
    QTcpSocket* m_headCmdClient;
    QTcpSocket* m_behaviorCmdClient;
    QTcpSocket* m_jointMonitorClient;

    QUdpSocket* m_UDPCamera;
    QByteArray m_currImageData;
    int m_width;
    int m_height;

    bool m_moveForward;

    AiboState* m_aiboState;
};

#endif // CONNECTIONTHREAD_H
